//Source file: D:\\test\\com\\ce\\pms\\charge\\model\\AbstractTrans.java

package com.ce.pms.charge.model;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.Table;

import org.springframework.core.annotation.Order;

import com.ce.pms.common.model.SysInfo;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.exception.BusinessException;
import com.ce.util.BlankUtil;
import com.sitechasia.webx.core.model.IDomainObject;

/**
 * 实体名称:交易
 * <ul><b>收费类交易: </b>
 * <li>001 本金交易;</li><li>002 减免交易;</li><li>003 调整交易;</li><li>004 滞纳金交易;</li>
 * </ul>
 * <ul><b>支付类交易: </b>
 * <li>005支付主交易;</li><li>006支付子交易(多重支付);</li>
 * </ul>
 *
 * 预交款账户 007收款交易;008抵冲交易 <br>
 *
 * 关联数据表:FEE_TRANSACTION <br>
 *
 * @author Adama Yue
 * @CreateDate:2008-7-11
 */
@Entity
@Table(name = "FEE_TRANSACTION")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
//@DiscriminatorColumn(name = "CLAZZ_CODE", discriminatorType = DiscriminatorType.STRING)
@org.hibernate.annotations.DiscriminatorFormula(
		"case when CLAZZ_CODE in('001','002','003','004') then 'DE' else 'CR' end"
)
public abstract class AbstractTrans implements IDomainObject{

	/**
	 * 主键
	 */
	@Id
	@GeneratedValue
	@Column(name = "TRANSACTION_ID")
	private Long transactionId;

	/**
	 * 收费周期
	 */
	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
	@JoinColumn(name = "PERIOD_ID",nullable=false)
	private PeriodDomain period;

	/**
	 * 交易码
	 */
	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
	@JoinColumn(name = "BIZ_CODE_ID",nullable=false)
	private BusinessCodeDomain businessCode;

	/**
	 * 交易关系集
	 */
	@org.hibernate.annotations.CollectionOfElements
	@JoinTable(
			name="FEE_TRA_R_TRA",
			joinColumns=@JoinColumn(name="TRANSACTION_ID1")
			)
	private Set<TraRtra> traRtras = new HashSet<TraRtra>();

	/**
	 * 绑定账户
	 */
	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
	@JoinColumn(name = "SUB_ACCOUNT_ID", nullable = false)
	private AbstractSubAccount bindingAccount;

	/**
	 * 备注
	 */
	@Column(name = "REMARK", length = 500)
	private String remark;

	/**
	 * 交易类型
	 */
	@Column(name="CLAZZ_CODE",nullable=false,insertable=true,updatable=false,length=3)
	private String clazz;

	/**
	 * 创建信息
	 */
	@Embedded
	private SysInfo sysInfo;

	/**
	 * @roseuid 48757D10004E
	 */
	public AbstractTrans() {
	}
	/**
	 * mini constructor
	 * @param period       收费周期
	 * @param businessCode 交易码
	 * @param staVersion   收费标准版本
	 * @param bindingAccount 子帐户
	 * @param clazz        类型
	 *                     收费类交易: 001本金交易;002减免交易;003调整交易;004滞纳金交易
	 *                     支付类交易: 005支付主交易;006支付子交易(多重支付);
	 * @param sysInfo      系统信息
	 */
	public AbstractTrans(PeriodDomain period, BusinessCodeDomain businessCode, AbstractSubAccount bindingAccount, String clazz, SysInfo sysInfo) {
		this.period = period;
		this.businessCode = businessCode;
		this.bindingAccount = bindingAccount;
		this.clazz = clazz;
		this.sysInfo = sysInfo;
	}


	public AbstractSubAccount getBindingAccount() {
		return bindingAccount;
	}


	public void setBindingAccount(AbstractSubAccount bindingAccount) {
		this.bindingAccount = bindingAccount;
	}


	public BusinessCodeDomain getBusinessCode() {
		return businessCode;
	}


	public void setBusinessCode(BusinessCodeDomain businessCode) {
		this.businessCode = businessCode;
	}


	public PeriodDomain getPeriod() {
		return period;
	}


	public void setPeriod(PeriodDomain period) {
		this.period = period;
	}


	public String getRemark() {
		return remark;
	}


	public void setRemark(String remark) {
		this.remark = remark;
	}

	public SysInfo getSysInfo() {
		return sysInfo;
	}

	public void setSysInfo(SysInfo sysInfo) {
		this.sysInfo = sysInfo;
	}

	public Set<TraRtra> getTraRtras() {
		return traRtras;
	}

	public void setTraRtras(Set<TraRtra> traRtras) {
		this.traRtras = traRtras;
	}

	public Long getTransactionId() {
		return transactionId;
	}

	public void setTransactionId(Long transactionId) {
		this.transactionId = transactionId;
	}
	/**
	 * @return the clazz
	 */
	public String getClazz() {
		return clazz;
	}
	/**
	 * @param clazz the clazz to set
	 */
	public void setClazz(String clazz) {
		this.clazz = clazz;
	}

	/**
	 * 功能描述: 检查必须字段 <br>
	 *
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-29  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public void checkRequiredField(){
		if (this.bindingAccount==null
				|| this.businessCode==null
				|| this.period==null
				|| BlankUtil.isBlank(this.clazz)
				|| this.sysInfo==null
				|| this.sysInfo.getCreator()==null
				|| this.sysInfo.getSysDate()==null) {
			throw new BusinessException("common:mustFill_null_exception",
					BusinessException.WARNING);
		}
	}

	/**
	 * 功能描述: 计算帐户余额 <br>
	 * @param moneyAmount
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-29  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:  因使用Hib方式更新时，如果同时有滞纳金在后台计算，
	 * 则有可能先拿到的账户余额没有加上此刻计算出来的滞纳金，可能造成脏数据更改。   <br>
	 */
	@Deprecated
	public void calculationBalance(BigDecimal moneyAmount){
		if (BlankUtil.isBlank(moneyAmount)
				|| BigDecimal.ZERO.compareTo(moneyAmount)==0) {
			return;
		}

		MathContext mc = new MathContext(SysrefcodeDO.DATA_PRICE_PRECISION,
										 RoundingMode.HALF_UP);
		BigDecimal balance = this.bindingAccount.getBalance();

		if (isDebitTransaction()) {
			balance = balance.add(moneyAmount, mc);
		}else{
			balance = balance.subtract(moneyAmount, mc);
		}

		this.bindingAccount.setBalance(balance);
	}

	/**
	 * 功能描述: 计算因挂起或解除挂起时帐户余额 <br>
	 * @param moneyAmount 挂起或解挂的相关交易金额
	 * @param isLiftinghangs 是否是解除挂起
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-29  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:  因使用Hib方式更新时，如果同时有滞纳金在后台计算，
	 * 则有可能先拿到的账户余额没有加上此刻计算出来的滞纳金，可能造成脏数据更改。   <br>
	 */
	@Deprecated
	public void calculationHangsBalance(BigDecimal moneyAmount,final Boolean isLiftinghangs){
		if (BlankUtil.isBlank(moneyAmount)
				|| BigDecimal.ZERO.compareTo(moneyAmount)==0
				|| BlankUtil.isBlank(isLiftinghangs)) {
			return;
		}

		MathContext mc = new MathContext(SysrefcodeDO.DATA_PRICE_PRECISION,
										 RoundingMode.HALF_UP);
		BigDecimal balance = this.bindingAccount.getBalance();
		if (isLiftinghangs) {
			balance = balance.add(moneyAmount, mc);
		}else{
			balance = balance.subtract(moneyAmount, mc);
		}

		this.bindingAccount.setBalance(balance);
	}

	/**
	 * 功能描述: 判断交易类型是否为应收交易 <br>
	 * @return　true 是应收交易　false 不是应收交易
	 *
	 * Create author:付湘辉 <br>
	 * Create on:2008-8-29  <br>
	 * Edit author:  <br>
	 * Edit on:    <br>
	 * Why:     <br>
	 */
	public Boolean isDebitTransaction(){
		return SysrefcodeDO.FEE_TRANSACTION_CLAZZ_PRINCIPAL.equals(this.clazz)
				|| SysrefcodeDO.FEE_TRANSACTION_CLAZZ_LATEFEES.equals(this.clazz)
				|| SysrefcodeDO.FEE_TRANSACTION_CLAZZ_RELIEF.equals(this.clazz)
				|| SysrefcodeDO.FEE_TRANSACTION_CLAZZ_ADJUSTMENT.equals(this.clazz);
	}
}
